import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

import 'db/db_help.dart';
import 'model/todo.dart';
import 'model/work_record.dart';

class WorkRecordState with ChangeNotifier {
  bool _isLoading = true;

  bool _loadMore = true;
  int _start = 0;

  DateTime _dateTime;

  WorkRecord _workRecord;

  WorkRecordState() {
    _dateTime = DateTime.now();
    _insertWorkRecord();
  }

  Future<List<Todo>> queryTodo(DateTime dateTime) async {
    final db = await dbHelp.database;
    final list = await queryTodoByTime(db,
    DateTime(dateTime.year, dateTime.month, dateTime.day, 0, 0, 0),
    DateTime(dateTime.year, dateTime.month, dateTime.day, 23, 59, 59),
    );
    return list;
  }

  DateTime get dateTime => _dateTime;


  set dateTime(DateTime value) {
    _dateTime = value;
    print(_dateTime.toLocal().toString());
    queryTodo(_dateTime);
    notifyListeners();
  }

  WorkRecord get workRecord => _workRecord;

  bool get loadMore => _loadMore;

  set loadMore(bool value) {
    _loadMore = value;
    notifyListeners();
  }

  printDebug() {
    print(_workRecord.toString());
  }

  setMorning() {
    _workRecord.morningFlag = true;
    notifyListeners();
    _updateRecord(_workRecord);
  }

  setNight() {
    _workRecord.nightFlag = true;
    notifyListeners();
    _updateRecord(_workRecord);
  }

  Future<void> addTodo(String note, DateTime dateTime, bool successFlag,
      bool waringFlag, bool errorFlag) async {
    TodoType todoType = successFlag
        ? TodoType.success
        : (waringFlag ? TodoType.waring : TodoType.error);
    Todo todo = await _insertTodo(Todo(
        note: note,
        time: dateTime,
        type: todoType,
        workRecordId: _workRecord.id));
    _workRecord.todoList.add(todo);
    _sort(_workRecord.todoList);
    notifyListeners();
  }

  Future<void> updateTodo(Todo todo) async {
    int index = _workRecord.todoList.indexWhere((t) => t.id == todo.id);
    await _updateTodo(todo);
    _workRecord.todoList[index] = todo;
    _sort(_workRecord.todoList);
    notifyListeners();
  }

  bool get morningFlag => _workRecord.morningFlag;

  bool get nightFlag => _workRecord.nightFlag;

  List<Todo> get todoList => _workRecord.todoList;

  bool get isLoading => _isLoading;

  void _sort(List<Todo> todoList) {
    todoList.sort((t1, t2) => t1.time.compareTo(t2.time));
  }

  Future<void> delete(Todo todo) async {
    _workRecord.todoList =
        _workRecord.todoList.where((t) => t.id != todo.id).toList();
    final db = await dbHelp.database;
    await deleteTodo(db, todo.id);
    notifyListeners();
  }

  int len() {
    return _workRecord.todoList.length;
  }

  Future<void> loadMoreTodo() async {
    final list = await _queryTodoByWorkRecord(workRecord, start: _start);
    if (list.isEmpty) {
      _loadMore = false;
    } else {
      _workRecord.todoList.addAll(
        list,
      );
      _start += 8;
    }
    notifyListeners();
  }

  Future<void> _insertWorkRecord() async {
    final time = DateTime.now();
    print("_insert WorkRecord");
    final db = await dbHelp.database;
    final record = await queryWorkRecordByDay(
      db,
      DateTime(time.year, time.month, time.day),
      DateTime(time.year, time.month, time.day, 24),
    );
    if (record == null) {
      print("第一次打卡 insert wordRecord");
      _workRecord = WorkRecord();
      await insertWorkRecord(db, _workRecord);
    } else {
      print("已存在打卡记录： ${record}");
      _workRecord = record;
      final list = await _queryTodoByWorkRecord(_workRecord);
      _workRecord.todoList = list;
      queryTodo(_dateTime);
      _start = list.length;
    }
    _isLoading = false;
    notifyListeners();
  }

  Future<void> _updateRecord(WorkRecord workRecord) async {
    final db = await dbHelp.database;
    await updateWorkRecord(
        db, workRecord.id, workRecord.morningFlag, workRecord.nightFlag);
  }

  Future<Todo> _insertTodo(Todo todo) async {
    final db = await dbHelp.database;
    await insertTodo(db, todo);
    return todo;
  }

  Future<void> _updateTodo(Todo todo) async {
    final db = await dbHelp.database;
    await updateTodoById(db, todo);
  }

  Future<List<Todo>> _queryTodoByWorkRecord(WorkRecord workRecord,
      {int start = 0}) async {
    final db = await dbHelp.database;
    return await queryTodoByWorkRecord(db, workRecord.id, start: start);
  }

}
